package org.taurusxi.apiprovider.conf

import com.google.gson.Gson
import com.google.gson.JsonIOException
import org.springframework.boot.autoconfigure.web.HttpMessageConverters
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpOutputMessage
import org.springframework.http.converter.HttpMessageNotWritableException
import org.springframework.http.converter.json.GsonHttpMessageConverter

import java.io.IOException
import java.io.OutputStreamWriter
import java.lang.reflect.Type
import java.nio.charset.Charset

/**
 * Created by xicheng on 16/5/4.
 */

@Configuration
open class HttpMsgConverterConfiguration {

    @Bean(name = arrayOf("gsonBean"))
    open fun gsonBean(): Gson {
        return Gson()
    }

    @Bean
    open fun customConverters(): HttpMessageConverters {

        val gsonConverters = LJGsonMessageConverter()
        return HttpMessageConverters(gsonConverters)
    }

    internal class LJGsonMessageConverter : GsonHttpMessageConverter() {

        private fun getHttpCharset(headers: HttpHeaders?): Charset {
            if (headers == null || headers.contentType == null || headers.contentType.charSet == null) {
                return GsonHttpMessageConverter.DEFAULT_CHARSET
            }
            return headers.contentType.charSet
        }

        @Throws(IOException::class, HttpMessageNotWritableException::class)
        override fun writeInternal(o: Any, outputMessage: HttpOutputMessage) {
            this.writeInternal(o, null, outputMessage)
        }

        @Throws(IOException::class, HttpMessageNotWritableException::class)
        override fun writeInternal(obj: Any?, type: Type?, outputMessage: HttpOutputMessage) {
            val writer = OutputStreamWriter(outputMessage.body, Charset.forName("UTF-8"))
            try {
                val gsonData = writeGsonData(obj!!, type)
                writer.write(gsonData)
                writer.flush()
                writer.close()
            } catch (ex: JsonIOException) {
                throw HttpMessageNotWritableException("Could not write JSON: " + ex.message, ex)
            }

        }

        private fun writeGsonData(o: Any, type: Type?): String {
            if (type != null) {
                return this.gson.toJson(o, type)
            } else {
                return this.gson.toJson(o)
            }
        }
    }
}

